import { useState, useEffect, Fragment, useRef } from 'react';
import { connect } from 'umi';
import { Modal, Tag, Select, message, Spin, Checkbox, Avatar, Button, Input, Popover } from 'antd';
import {
  ExportOutlined,
  BarsOutlined,
  EditOutlined,
  CloseCircleFilled,
  UpOutlined,
  DownOutlined,
} from '@ant-design/icons';
import './index.less';
import { getAuthority } from '@/utils/authority';
import { debounce } from 'lodash';
import type { ProFormInstance } from '@ant-design/pro-form';
// 添加图标
import AddImg from '@/assets/add.png';
import LoadMore from './loadMore';

// 全局变量
const ossUrl = process.env.OSS_URL;
// 获取最大组织id
const maxOrgId: string = getAuthority()?.maxOrg?.id;

const { Option } = Select;

const CommonSelectUser = (props: {
  dispatch?: any;
  title?: string; // 弹窗标题(选传)
  disabled?: boolean; // 设置disabled(选传)
  initList?: Array<{ nickName: string; id?: string }>; // 初始列表（选传）
  initCanDelete?: boolean; // 设置初始值能否删除
  placeholder?: string; // 占位符（选传）
  multiple?: boolean; // 单选：false   多选：true (必传)
  propsOrgId?: string; // 是否有orgId, 如果有，则根据orgId查询以下的人员，如果没有，则使用maxOrgId查询(选传)
  mode?: string; // 选择人员的方式，适配各种情况（可选） 'setUserManage'：直接设置组织管理员
  maxCheckedListLength?: number; // 最大选中的人数（不传则为200）
  showUserInfo?: boolean; // 显示人员信息
  onChange?: (checkedList: any[]) => void; // form.item 的
  onSuccessCallback?: (checkedList: any[], orgId?: string, userId?: string) => void; // 选择成功后的回调（可选）
  isCheck?: boolean; // 是否越权校验  true：需要校验   false: 跳过校验
  btnText?: string; // 按钮文字
  onSuccessDeleteUser?: (iserId: string, orgId: string) => void; // 删除人员成功回调
  selectTypeStr?: string; // 选择人员类型
}) => {
  const formRef = useRef<ProFormInstance>();
  const {
    dispatch,
    title = '选择人员', // 弹窗标题
    disabled = false, // 设置disabled
    initList = [], // 初始选中的列表
    initCanDelete = true, // 设置初始值能否删除  默认true：可以删
    placeholder = '请选择人员', // 占位符
    multiple = false, // 单选：false   多选：true
    propsOrgId = maxOrgId, // 是否有orgId, 如果有，则根据orgId查询以下的人员，如果没有，则使用maxOrgId查询(选传)
    mode,
    maxCheckedListLength = 200, // 最大选中的人数（不传则为200）
    showUserInfo = false,
    onChange,
    onSuccessCallback,
    isCheck = true,
    btnText = '选择人员',
    onSuccessDeleteUser,
    selectTypeStr = '企业',
  } = props;

  // 选择人员弹窗visible
  const [selectUserVisible, setSelectUserVisible] = useState<boolean>(false);
  // 人员搜索的value
  const [searchUserName, setSearchUserName] = useState<any>(null);
  // 人员搜索的list
  const [searchUserList, setSearchUserList] = useState<any[]>([]);
  // 加载loading
  const [loading, setLoading] = useState<boolean>(false);
  // 面包屑list
  const [orgTabList, setOrgTabList] = useState<any[]>([]);
  // 查询的组织结果列表
  const [orgList, setOrgList] = useState<any[]>([]);
  // 查询的人员结果列表
  const [subUserList, setSubUserList] = useState<any[]>([]);
  // 选中的list
  const [checkedList, setCheckedList] = useState<any[]>([]);
  // 最终选中的list
  const [finallList, setFinallList] = useState<any[]>([]);
  // 展示单位内容
  const [isShowUnit, setIsShowUnit] = useState<boolean>(true);
  // 人员信息弹窗loading
  const [popoverLoading, setPopoverLoading] = useState(false);
  // 人员信息弹窗详情
  const [userInfo, setUserInfo] = useState<any>(null);

  // 是否还有更多数据
  const [hasMore, setHasMore] = useState<boolean>(false);
  // 记录当前状态，是加载中...，还是点击加载更多
  const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false);
  // 当前页码
  const [current, setCurrent] = useState<number>(1);
  const pageSize: number = 100;
  // 缓存当前orgId
  const currOrgRef = useRef<string>('');

  // 根据组织id查询人员选择框人员信息
  const getSelectUserListByOrgId = async (orgId?: string, _current?: number) => {
    setLoading(true);
    setIsLoadingMore(true);
    const orgIdAf = orgId || currOrgRef.current;
    await dispatch({
      type: 'commonSelectUser/findSelectUserPageList',
      payload: {
        orgId: orgIdAf || propsOrgId,
        current: _current || current,
        pageSize,
      },
      callback: (res: any) => {
        const { code, data, msg } = res;
        if (code === 1) {
          const { list: listN = [], current: current1 } = data || {};
          let isMore: boolean = true;
          if (listN.length < pageSize) {
            isMore = false;
          } else {
            setIsLoadingMore(false);
          }
          setHasMore(isMore);
          setSubUserList((prevState) => [...prevState, ...listN]); // 这是重点，子组件调用父组件方法，并且重新赋值时的操作
          setCurrent(current1 + 1); // 重新设置当前页码
          currOrgRef.current = orgIdAf; // 缓存当前orgId
        } else {
          message.error(msg);
        }
      },
    });
    setLoading(false);
  };

  // 人员选择框获取当前或者下级
  const getCurrentUserByOrgId = (orgId: string) => {
    setLoading(true);
    setSubUserList([]);
    getSelectUserListByOrgId(orgId, 1); // 获取第一页初始的用户列表
    setLoading(false);
  };

  useEffect(() => {
    if (initList !== finallList && initList.length > 0) {
      setCheckedList(initList);
      setFinallList(initList);
      onChange?.(initList);
    }
  }, [initList[0]?.id]);

  useEffect(() => {
    if (selectUserVisible) {
      setCheckedList(finallList);
      getCurrentUserByOrgId(propsOrgId);
    }
  }, [selectUserVisible]);

  // 展示弹窗
  const showModal = () => {
    setSelectUserVisible(true);
  };

  // 取消
  const handleCancle = () => {
    setSelectUserVisible(false);
  };

  // 确定
  const handleOk = () => {
    if (onSuccessCallback) {
      if (checkedList.length === 0) {
        message.info('请选择人员');
        return;
      }
      onSuccessCallback?.(checkedList, propsOrgId, initList?.[0]?.id);
    }
    onChange?.(checkedList);
    setCheckedList(checkedList);
    setFinallList(checkedList);
    setSelectUserVisible(false);
  };

  // 删除某个人员
  const handleDelete = (id: string) => {
    const hasId = initList.findIndex((value) => value.id === id); // 初始的列表是否有该id的人员  > -1
    if (!initCanDelete && hasId > -1) {
      // 该人员无法修改
      message.error('该人员无法修改');
      return;
    }
    const resultList: any = [];
    checkedList.map((item: any) => {
      if (item.id !== id) {
        resultList.push(item);
      }
    });
    setCheckedList(resultList);
  };

  // 输入时查询
  const handleSearch = debounce((value: any) => {
    setSearchUserName(value || null);
    setSearchUserList([]);
    if (value) {
      dispatch({
        type: 'commonSelectUser/findSelectUserByUserName',
        payload: {
          userName: value,
          orgId: propsOrgId,
        },
        callback: (res: any) => {
          const { code, data } = res;
          if (code === 1) {
            setSearchUserList(data);
          }
        },
      });
    }
  }, 200);

  // 失去焦点回调(清空)
  const handleBlur = () => {
    setSearchUserList([]);
    setSearchUserName(null);
  };
  // 选择某个下拉回调
  const handleChange = (value: any) => {
    const stringToObject: any = JSON.parse(value); // 选中的object
    if (multiple) {
      // 如果是多选，则看这个id在不在checkedList里面，如果不在，则push
      const changeCheckedList: any[] = [...checkedList];
      const ids: any[] = checkedList.map((v) => {
        return v.id;
      });
      const maxListLength: number =
        maxCheckedListLength && maxCheckedListLength <= 200 && maxCheckedListLength > 0
          ? maxCheckedListLength
          : 200; // 最多200人，如果不传或者传了大于200
      if (ids.includes(stringToObject.id)) {
        message.info('该人员已被选中');
      } else if (checkedList.length >= maxListLength) {
        message.info(`选择超出限制，最多选择${maxListLength}人！`);
      } else {
        changeCheckedList.push({
          id: stringToObject.id,
          nickName: stringToObject.nickName,
          logo: stringToObject.logo,
          orgId: stringToObject.orgId,
        });
        setCheckedList(changeCheckedList);
      }
    } else {
      // 单选，则替换
      const changeCheckedList: any[] = [
        {
          id: stringToObject.id,
          nickName: stringToObject.nickName,
          logo: stringToObject.logo,
          orgId: stringToObject.orgId,
        },
      ];
      setCheckedList(changeCheckedList);
    }
    // 选择完毕后清空
    handleBlur();
  };

  // checkBox是否选择人员（单选）
  const handleOnChangeCheckUser = (
    id: string,
    nickName: string,
    logo: string,
    orgId: string,
    e: any,
  ) => {
    if (e.target.checked) {
      // 如果是选中
      if (multiple) {
        // 如果是多选，则push
        const changeCheckedList: any[] = [...checkedList];
        changeCheckedList.push({
          id,
          nickName,
          logo,
          orgId,
        });
        const maxListLength: number =
          maxCheckedListLength && maxCheckedListLength <= 200 && maxCheckedListLength > 0
            ? maxCheckedListLength
            : 200; // 最多200人，如果不传或者传了大于200
        if (changeCheckedList.length > maxListLength) {
          message.info(`选择超出限制，最多选择${maxListLength}人！`);
        } else {
          setCheckedList(changeCheckedList);
        }
      } else {
        // 如果是单选，则替换
        const changeCheckedList: any[] = [
          {
            id,
            nickName,
            logo,
            orgId,
          },
        ];
        setCheckedList(changeCheckedList);
      }
    } else {
      // 取消选中，删除
      handleDelete(id);
    }
  };
  // checkBox是否选择上人员（单选）
  const handleCheckedUser = (id: string) => {
    let result: boolean = false;
    checkedList.map((item) => {
      if (item.id === id) {
        result = true;
      }
    });
    return result;
  };

  // 选择checkbox（全选人员）
  const onChangeAll = (e: any) => {
    const changeCheckedList: any[] = [...checkedList];
    if (e.target.checked) {
      subUserList.map((item: any) => {
        const hasId = checkedList.findIndex((value) => value.id === item.id);
        if (hasId === -1) {
          changeCheckedList.push(item);
        }
      });
    } else {
      subUserList.map((item: any) => {
        if (changeCheckedList.length > 0) {
          let t = 0;
          for (let i = 0; i < changeCheckedList.length; i++) {
            if (changeCheckedList[i].id === item.id) {
              const hasId = initList.findIndex((value) => value.id === item.id); // 初始的列表是否有该id的人员  > -1
              if (initCanDelete || hasId === -1) {
                // 删除起始坐标为t的值
                changeCheckedList.splice(t, 1);
              }
            }
            t++;
          }
        }
      });
    }
    const maxListLength: number =
      maxCheckedListLength && maxCheckedListLength <= 200 && maxCheckedListLength > 0
        ? maxCheckedListLength
        : 200; // 最多200人，如果不传或者传了大于200
    if (changeCheckedList.length > maxListLength) {
      message.info(`选择超出限制，最多选择${maxListLength}人！`);
    } else {
      setCheckedList(changeCheckedList);
    }
  };
  // checkBox是否选择（全选）
  const handleCheckAll = () => {
    let result: boolean = true;
    subUserList.map((item: any) => {
      const hasId = checkedList.findIndex((value) => value.id === item.id);
      if (hasId === -1) {
        result = false;
      }
    });
    return result;
  };
  // 多选删除人员
  const handleMultipleDelete = (id: string, orgId: string) => {
    const hasId = initList.findIndex((value) => value.id === id); // 初始的列表是否有该id的人员  > -1
    if (!initCanDelete && hasId > -1) {
      // 该人员无法修改
      message.error('该人员无法修改');
      return;
    }
    const resultList: any = [];
    checkedList.map((item: any) => {
      if (item.id !== id) {
        resultList.push(item);
      }
    });
    setCheckedList(resultList);
    setFinallList(resultList);
    onChange?.(resultList);

    // 如果删除人员有回调，则调用方法
    if (onSuccessDeleteUser) {
      onSuccessDeleteUser(id, orgId);
    }
  };

  // 改变展示单位
  const handleChangeShowUnit = () => {
    setIsShowUnit(!isShowUnit);
  };

  // 获取人员信息
  const getUserInfo = (id: any) => {
    setPopoverLoading(true);
    dispatch({
      type: 'residentMobility/findMoveOutUserInfo',
      payload: { id },
      callback: (res: any) => {
        const { code, data, msg } = res;
        if (code === 1) {
          setUserInfo(data);
        } else {
          message.error(msg || '服务器开小差了~');
        }
        setPopoverLoading(false);
      },
    });
  };

  // 展示人员信息
  const userModalChange = (bol: boolean, item: any) => {
    if (bol) {
      getUserInfo(item.id);
    } else {
      setUserInfo(null);
    }
  };

  // 气泡弹窗内容
  const popoverContent = (
    <Spin spinning={popoverLoading}>
      <div>
        <p>姓名：{userInfo?.nickName}</p>
        <p>性别：{userInfo && userInfo.gender === 'M' ? '男' : '女'}</p>
        <p>生日：{userInfo?.birthday}</p>
        <p>身份证号：{userInfo?.identityCard}</p>
        <p>登录名：{userInfo?.username}</p>
        <p>手机号：{userInfo?.mobile}</p>
        <p>紧急联系方式：{userInfo?.emergencyContact}</p>
        <p>户籍地址：{userInfo?.householdRegisterName + userInfo?.householdRegisterAddress}</p>
      </div>
    </Spin>
  );

  // 加载更多
  const loadMoreUserData = () => {
    if (isLoadingMore || !hasMore) {
      return;
    }
    getSelectUserListByOrgId();
  };

  // 多个管理员回显
  const adminListFm = (list: any) => {
    if (list) {
      let arr: any = [];
      list.forEach((item: any) => {
        arr.push(item.nickName);
      });
      return arr.join('、');
    }
  };

  return (
    <Fragment>
      {!multiple && !mode && (
        <div className="disabledFieldPropsCom" onClick={!disabled ? showModal : () => { }}>
          <Input
            value={finallList.length > 0 ? finallList[0].nickName : ''}
            suffix={<ExportOutlined />}
            placeholder={placeholder || '请选择人员'}
            allowClear={false}
            disabled={disabled}
          />
        </div>
      )}
      {!multiple && mode === 'setUserManage' && (
        <div>
          {finallList && finallList.length > 0 ? (
            <span style={{ paddingRight: '8px' }}>{finallList[0].nickName}</span>
          ) : (
            <span style={{ color: '#4D91FB', paddingRight: '8px' }}>暂无</span>
          )}
          <span title="去设置管理人员" onClick={showModal}>
            <EditOutlined style={{ color: '#4D91FB', cursor: 'pointer' }} />
          </span>
        </div>
      )}
      {multiple && mode === 'setUserManage' && (
        <div>
          {finallList && finallList.length > 0 ? (
            <span style={{ paddingRight: '8px' }}>{adminListFm(finallList)}</span>
          ) : (
            <span style={{ color: '#4D91FB', paddingRight: '8px' }}>暂无</span>
          )}
          <span title="去设置管理人员" onClick={showModal}>
            <EditOutlined style={{ color: '#4D91FB', cursor: 'pointer' }} />
          </span>
        </div>
      )}
      {multiple && mode === 'btn' && (
        <Button
          type="default"
          onClick={() => {
            setFinallList([]);
            showModal();
          }}
        >
          {btnText}
        </Button>
      )}
      {multiple && !mode && (
        <div className="multipleUsersWrap">
          {finallList &&
            finallList.length > 0 &&
            finallList.map((item: any) => {
              const name =
                item.nickName.length > 3 ? `${item.nickName.slice(0, 3)}...` : item.nickName;
              const avatarName = item.nickName?.slice(-2);
              const hasId = initList.findIndex((value) => value.id === item.id); // 初始的列表是否有该id的人员  > -1
              return (
                <div key={`finall_item_${item.id}`} className="userSelectDiv">
                  {!disabled && (hasId === -1 || initCanDelete) && (
                    <CloseCircleFilled
                      className="close_icon"
                      onClick={() => {
                        if (onSuccessDeleteUser) {
                          Modal.confirm({
                            title: '确认删除该人员吗？',
                            onOk: () => {
                              handleMultipleDelete(item.id, item.orgId);
                            },
                          })
                        } else {
                          handleMultipleDelete(item.id, item.orgId);
                        }
                      }}
                    />
                  )}

                  {showUserInfo ? (
                    <Popover
                      placement="right"
                      content={popoverContent}
                      trigger="click"
                      onVisibleChange={(bol) => {
                        userModalChange(bol, item);
                      }}
                    >
                      <Avatar src={ossUrl + item.logo}>{avatarName}</Avatar>
                    </Popover>
                  ) : (
                    <Avatar src={ossUrl + item.logo}>{avatarName}</Avatar>
                  )}
                  <div className="userName">{name}</div>
                </div>
              );
            })}
          {!disabled && (
            <div className="addBtn" onClick={showModal}>
              <img className="addImg" src={AddImg} alt="" />
              <div className="userName">添加人员</div>
            </div>
          )}
        </div>
      )}
      <Modal
        title={title}
        className="commonSelectUser"
        destroyOnClose
        maskClosable={false}
        visible={selectUserVisible}
        onOk={handleOk}
        onCancel={handleCancle}
        width={870}
        footer={
          <div className="selectUserFooter">
            <div className="selectUserCount">共选择{checkedList.length}人</div>
            <div className="selectOperation">
              <Button onClick={handleCancle}>取消</Button>
              <Button type="primary" onClick={handleOk}>
                确定
              </Button>
            </div>
          </div>
        }
      >
        <div className="selectUserWrap">
          <div className="choose_left">
            {checkedList &&
              checkedList.length > 0 &&
              checkedList.map((item: any) => {
                const hasId = initList.findIndex((value) => value.id === item.id); // 初始的列表是否有该id的人员  > -1
                return (
                  <Tag
                    closable={hasId === -1 || initCanDelete}
                    onClose={() => {
                      handleDelete(item.id);
                    }}
                    key={`checked_item_${item.id}`}
                  >
                    {item.nickName}
                  </Tag>
                );
              })}
            <Select
              dropdownClassName="searchUserWrap"
              showSearch={true}
              placeholder="人员搜索"
              value={searchUserName}
              showArrow={false}
              filterOption={false}
              onSearch={handleSearch}
              onChange={handleChange}
              notFoundContent={null}
              dropdownMatchSelectWidth={false}
              autoFocus={true}
              bordered={false}
              onBlur={handleBlur}
            >
              {searchUserList &&
                searchUserList.length > 0 &&
                searchUserList.map((item: any) => {
                  const object2String = JSON.stringify(item);
                  const avatarName = item.nickName?.slice(-2);
                  return (
                    <Option
                      key={`search_item_${item.id}`}
                      value={object2String}
                      className="searchUserWrapOption"
                    >
                      <Avatar src={ossUrl + item.logo}>{avatarName}</Avatar>
                      <div style={{ marginTop: '-2px' }}>{item.nickName}</div>
                    </Option>
                  );
                })}
            </Select>
          </div>
          <div className="choose_right" id="user_choose_right">
            <div className="user_common_wrap">
              <div className="user_common_top" onClick={handleChangeShowUnit}>
                <div className="top_title">从{selectTypeStr}中选择</div>
                <div className="top_icon">{isShowUnit ? <UpOutlined /> : <DownOutlined />}</div>
              </div>
              {isShowUnit && (
                <div className="unit_con">
                  <div className="org_tabs">
                    {orgTabList &&
                      orgTabList.length > 0 &&
                      orgTabList.map((item: any) => {
                        return (
                          <div
                            onClick={() => {
                              getCurrentUserByOrgId(item.id, 0);
                            }}
                            className="tab_item"
                            key={`org_tab_item_${item.id}`}
                          >
                            {item.shortName}
                          </div>
                        );
                      })}
                  </div>
                  <div className="org_list">
                    <Spin size="large" spinning={loading}>
                      {orgList &&
                        orgList.length > 0 &&
                        orgList.map((item: any) => {
                          return (
                            <div className="org_item" key={`org_item_${item.id}`}>
                              <div>
                                {item.shortName} ({item.userCount}人)
                              </div>
                              {item.userCount > 0 && (
                                <div
                                  className="choose_next"
                                  onClick={() => {
                                    getCurrentUserByOrgId(item.id, 0);
                                  }}
                                >
                                  <BarsOutlined />
                                  &nbsp;&nbsp;下级
                                </div>
                              )}
                            </div>
                          );
                        })}
                      {multiple && subUserList && subUserList.length > 0 && (
                        <div className="org_item">
                          <Checkbox
                            onChange={(e) => {
                              onChangeAll(e);
                            }}
                            checked={handleCheckAll()}
                          >
                            全选
                          </Checkbox>
                        </div>
                      )}
                      {subUserList &&
                        subUserList.length > 0 &&
                        subUserList.map((item: any) => {
                          return (
                            <div className="user_item" key={`subUser_item_${item.id}`}>
                              <Checkbox
                                onChange={(e) => {
                                  handleOnChangeCheckUser(
                                    item.id,
                                    item.nickName,
                                    item.logo,
                                    item.orgId,
                                    e,
                                  );
                                }}
                                checked={handleCheckedUser(item.id)}
                              >
                                <Avatar src={ossUrl + item.logo}>
                                  {item.nickName.substring(
                                    item.nickName.length - 2,
                                    item.nickName.length,
                                  )}
                                </Avatar>
                                {item.nickName}
                              </Checkbox>
                            </div>
                          );
                        })}
                    </Spin>
                  </div>
                </div>
              )}
            </div>

            {hasMore ? (
              <LoadMore
                isLoadingMore={isLoadingMore}
                loadMoreFn={loadMoreUserData}
                propsId="user_choose_right"
              />
            ) : (
              <div></div>
            )}
          </div>
        </div>
      </Modal>
    </Fragment>
  );
};
export default connect()(CommonSelectUser);
